require("Entity")

Container = class("Container", Entity)


--- statics

function Container.Everywhere(types)

	local containers = {}
	
	for i, type in ipairs(types) 
	do
		if gField.entityTypes[type] 
		then
			for containerName, containerEntity in pairs(gField.entityTypes[type]) do
				
				containers[containerEntity] = 1
			end 
		end
	end
	
	return containers	
end


--- members

function Container:initialize(name, type)

	if not type 
	then
		type = "Container"
	end
	
	Entity.initialize(self, type, name)
	
	self:registerEntityType("Container")			-- we register Container type to insure that sub class with their own type are also register as Container
	
	self.subContainers = {}	
end  

---

function Container:addSubContainer(container)

	self.subContainers[container.name] = container
	
	return container
end


--- this function can only work with entities that implement the function : 
---		isPotentialyIn(container)

function Container:applyToCotainedEntities(caller, type, functionToApply)

	if gField.entityTypes[type]
	then
		for entityName, entity in pairs(gField.entityTypes[type]) 
		do
			if entity:isPotentialyIn(self) 
			then
				functionToApply(caller, entity)
			end
		end
	end
end


--- this function can only work with containers that implement the function : 
---		getLinksToPropagateObservation()
---		getLinksToObserve()

function Container:propagateObservation()

	if self.lastPropagationBeat ~= gField.beat 
	then
		gDramaManager:onContainerSoonToBeObserved(self)
		
		
		-- mark this location as observed at the current beat
		
		gLogger:enterGroup("Observe container " .. self.type .. " " .. self.name)
		
		gField.world.observedLocations[self.name] = self
		self.lastPropagationBeat = gField.beat
		
		
		-- propagate observation to relevant linked containers
		
		for linkName, linkEntity in pairs(self:getLinksToPropagateObservation()) 
		do
			linkEntity:observe(self)
			
			if linkEntity:isEnabled() 
			then
				linkEntity:getOtherSide(self):propagateObservation()
			end
		end
		
		
		-- collapse the links to my neighborhood
		
		for linkName, linkEntity in pairs(self:getLinksToObserve()) 
		do
			linkEntity:observe(self)
		end
		
		gLogger:leaveGroup()
	end
end